package com.dycn.posdashboard.dbhelper;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.ChildBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import com.dycn.posdashboard.data.DataSourceConfig;

public class DynamicDataSourceRegisterBean implements ApplicationContextAware,ApplicationListener {
    protected final Log log = LogFactory.getLog(getClass());
	private ApplicationContext applicationContext = null; 


	@Override
	public void setApplicationContext(ApplicationContext app)
			throws BeansException {
		// TODO Auto-generated method stub
		this.applicationContext=app;
	}

	@Override
	public void onApplicationEvent(ApplicationEvent event) {   
        if(event instanceof ContextRefreshedEvent ){//如果是容器refresh事件
        	log.info("容器refresh事件~~~~");
			try { 
				init(); 
			} catch (Exception e) { 
			    e.printStackTrace(); 
			//System.out.println(event.getClass().getSimpleName()+" 事件已发生！");
			}
        }
	}
	
	private void init(){
//		ServicesResultObject<List<MetaModelSource>> servicesResultObject=this.metaModelServices.getMetaModelSourceList(DataBaseUser.MAIN_USER);
//		if(!servicesResultObject.isSuccess()){
//			log.error("初始化系统数据源失败~~~~");
//		}else{
//			List<MetaModelSource> metaModelSourceList=servicesResultObject.getReturnObj();
//			Map<String, DataSourceConfig> mapDataSourceConfigMap=new HashMap<String, DataSourceConfig>();
//			if(metaModelSourceList!=null&&metaModelSourceList.size()!=0){
//				for(MetaModelSource someMetaModelSource:metaModelSourceList){
//					mapDataSourceConfigMap.put(someMetaModelSource.getSourceKey(), someMetaModelSource);
//				}
//				try {
//					regDynamicBean(mapDataSourceConfigMap);
//					log.info("初始化系统数据源完成~~~~");
//				} catch (Exception e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//					log.error("初始化系统数据源失败~~~~");
//				}
//			}
//		}
		
	}
	
	public void regDynamicBean(Map<String, DataSourceConfig> mapDataSourceConfig) throws Exception {  
        // 解析属性文件，得到数据源Map  
        //Map<String, DataSourceInfo> mapCustom = parsePropertiesFile("hummer.properties");  
        // 把数据源bean注册到容器中 
		//从数据库中读取已经存在的配置信息 初始化数据源
        addSourceBeanToApp(mapDataSourceConfig);  
        //System.out.println(app.getBean("mydata" + 1));  
  
    } 
	
	public boolean validationDataSourceConfig(DataSourceConfig someDataSourceConfig){
//		DynamicDataSource dynamicDataSource = (DynamicDataSource) applicationContext.getBean("dynamicDs");
//        Map<String, XBasicDataSource> targetDataSources =(Map<String, XBasicDataSource>)dynamicDataSource  
//                .getTargetDataSources();
        XBasicDataSource cpds = (XBasicDataSource) applicationContext.getBean(someDataSourceConfig.getSourceKey());
        try {
			cpds.getConnection();
			return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
        
	}
	
	/**
	 * 
	 * @param mapCustom
	 * @throws Exception
	 */
    private void addSourceBeanToApp(Map<String, DataSourceConfig> mapCustom)  
            throws Exception {  
        DefaultListableBeanFactory acf = (DefaultListableBeanFactory) applicationContext  
                .getAutowireCapableBeanFactory();  
        BeanDefinition beanDefinition;  
        Iterator<String> iter = mapCustom.keySet().iterator(); 
        //Map<String, XBasicDataSource> willUpdateSoruceMap=new HashMap<String, XBasicDataSource>();
        DynamicDataSource dynamicDataSource = (DynamicDataSource) applicationContext.getBean("dynamicDs");  
        Map<String, XBasicDataSource> targetDataSources =(Map<String, XBasicDataSource>)dynamicDataSource  
                .getTargetDataSources(); 
        while (iter.hasNext()) {  
            String beanKey = iter.next(); 
            DataSourceConfig someDataSourceConfig=mapCustom.get(beanKey);
            // 得到Bean定义，并添加到容器中  
            //可能要根据不同的数据库类型来获取相对应的定义信息
            beanDefinition = new ChildBeanDefinition("dataSource_metadata_main");  
            // 注意：必须先注册到容器中，再得到Bean进行修改，否则数据源属性不能有效修改  
            acf.registerBeanDefinition(beanKey, beanDefinition);  
            // 再得到数据源Bean定义，并修改连接相关的属性  
            XBasicDataSource cpds = (XBasicDataSource) applicationContext.getBean(beanKey);  
  
            cpds.setUrl(someDataSourceConfig.getConnetionURL());  
            cpds.setUsername(someDataSourceConfig.getDbLoginUser());  
            cpds.setPassword(someDataSourceConfig.getDbLoginPwd());  
            cpds.setDriverClassName(someDataSourceConfig.getDriverClassName()); 
            cpds.setValidationQuery(someDataSourceConfig.getValidationQuery());
            log.info("初始化系统数据源完成sourceKey~~~~"+beanKey);
            log.info("初始化系统数据源完成getConnetionURL~~~~"+someDataSourceConfig.getConnetionURL());
            log.info("初始化系统数据源完成getDbLoginUser~~~~"+someDataSourceConfig.getDbLoginUser());
            log.info("初始化系统数据源完成getDbLoginPwd~~~~"+someDataSourceConfig.getDbLoginPwd());
            
            targetDataSources.put(beanKey, cpds);
        }  
        
        //更新datasource mapping
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.afterPropertiesSet();  

    }  
}
